﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Configuration;
using DotNETX.Version.IniVersionInfo;

namespace DotNETX.Version
{

    [ServiceBehavior(
        InstanceContextMode = InstanceContextMode.PerCall,
        ConcurrencyMode = ConcurrencyMode.Multiple,
        UseSynchronizationContext = false)]
    public class VersionService : IVersionService
    {
        public const string CONFIG_KEY_VERSIONINI_LOCATION = "DotNETX.Version.VersionService.VersionIniLocation";
        public const int MIN_READ_INTERVAL_IN_SECOND = 60;

        public void ReadPath()
        {
            if (null == Path)
            {
                lock (sLockObj)
                {
                    if (Path == null)
                    {
                        string configPath = TryGetAppSetting(this.GetType(), CONFIG_KEY_VERSIONINI_LOCATION);
                        Path = VersionInfoUtils.LocateVersionIni(this.GetType(), configPath);
                    }
                }
            }
        }

        public VersionInfo GetLatestVersion()
        {
            // 读取版本配置文件位置
            if (null == Path)
            {
                ReadPath();
                if (Path == null) return null;
            }
            try
            {
                // 判断是否需要重新读取配置文件
                if (null == CacheVersionInfo || (LastIniReadTime - DateTime.Now).TotalSeconds > MIN_READ_INTERVAL_IN_SECOND)
                {
                    lock (sLockObj)
                    {
                        if (null == CacheVersionInfo || (DateTime.Now - LastIniReadTime).TotalSeconds > MIN_READ_INTERVAL_IN_SECOND)
                        {
                            CacheVersionInfo = VersionInfoUtils.ReadVersionInfo(Path);
                            LastIniReadTime = DateTime.Now;
                        }
                    }
                }

                return CacheVersionInfo;
            }
            catch (Exception ex)
            {
                throw new FaultException(new FaultReason("版本读取失败！"));
            }
        }

        public bool SetCurrentVersion(VersionInfo versionInfo)
        {
            // 读取版本配置文件位置
            if (null == Path)
            {
                ReadPath();
                if (Path == null) return false;
            }

            try
            {
                lock (sLockObj)
                {
                    VersionInfoUtils.WriteVersionInfo(Path, versionInfo);
                    CacheVersionInfo = VersionInfoUtils.ReadVersionInfo(Path);
                    LastIniReadTime = DateTime.Now;
                }
                if (CacheVersionInfo.VersionName != versionInfo.VersionName) return false;
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        protected static object sLockObj = new object();

        public static string Path { get; set; }
        protected static DateTime LastIniReadTime { get; set; }
        protected static VersionInfo CacheVersionInfo { get; set; }


        private static string TryGetAppSetting(Type type, string key)
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(type.Assembly.Location);
            if (config.AppSettings.Settings.AllKeys.Contains(key))
            {
                return config.AppSettings.Settings[key].Value;
            }
            else
            {
                return ConfigurationManager.AppSettings[key];
            }
        }
    }
}
